package com.czk.stream;

import java.util.Optional;
import java.util.stream.Stream;

/**
 * stream流式操作各种简化api
 *
 * @Author ChenZhangKun
 * @Date 2020/11/16 9:12
 */
public class StreamDemo_1 {

    public static void main(String[] args) {
        // concat
        Stream.concat(Stream.of(1, 2, 3), Stream.of(4, 5)).forEach(x -> System.out.print(x + "  "));
        System.out.println();
        // distinct去重
        Stream.of(1, 2, 2, 3, 3).distinct().forEach(x -> System.out.print(x + " "));
        System.out.println();
        // filter过滤
        Stream.of(1, 2, 3, 4, 5).filter(x -> x > 3).forEach(x -> System.out.print(" " + x));
        System.out.println();
        // map方法，将stream中的元素按照函数进行操作
        Stream.of("a", "b").map(x -> x.toUpperCase()).forEach(x -> System.out.print(x + " "));
        System.out.println();
        // flatMap方法与map方法类似，都是将原Stream中的每一个元素通过转换函数转换，不同的是，该换转函数的对象是一个Stream，也不会再创建一个新的Stream，而是将原Stream的元素取代为转换的Stream。
        // 如果转换函数生产的Stream为null，应由空Stream取代。flatMap有三个对于原始类型的变种方法，分别是：flatMapToInt，flatMapToLong和flatMapToDouble。
        Stream.of(1, 2, 3).flatMap(x -> Stream.of(x * 10)).forEach(x -> System.out.print(x + " "));
        System.out.println();
        // peek方法生成一个包含原Stream的所有元素的新Stream，同时会提供一个消费函数（Consumer实例），新Stream每个元素被消费的时候都会执行给定的消费函数，并且消费函数优先执行
        Stream.of(1, 2, 3, 4, 5)
                .peek(integer -> System.out.println("accept:" + integer))
                .forEach(System.out::print);
        System.out.println();
        // skip,跳过前几个元素
        Stream.of(1, 2, 3).skip(2).forEach(x -> System.out.print(x + " "));
        System.out.println();
        // 元素个数count
        System.out.println(Stream.of(1, 2, 3).count());
        System.out.println();
        // foreach
        Stream.of(1, 2, 3).forEach(x -> System.out.print(x + " "));
        System.out.println();
        // foreachOrder 指定了元素顺序
        Stream.of(5, 2, 1, 4, 3)
                .forEachOrdered(integer -> {
                    System.out.println("integer:" + integer);
                });
        // max方法根据指定的Comparator，返回一个Optional，该Optional中的value值就是Stream中最大的元素。
        Optional<Integer> max = Stream.of(1, 2, 3, 8, 9, 4, 5).max((o1, o2) -> o2 - o1);
        System.out.print(max.get());
        System.out.println();
        // min方法根据指定的Comparator，返回一个Optional，该Optional中的value值就是Stream中最小的元素。
        // (o1, o2) -> o2 - o1是comprator，真正起作用的是他
        Optional<Integer> min = Stream.of(1, 2, 3, 8, 9, 4, 5).min((o1, o2) -> o2 - o1);
        System.out.print(min.get());
        System.out.println();
        // allMatch操作用于判断Stream中的元素是否全部满足指定条件。如果全部满足条件返回true，否则返回false。
        boolean b = Stream.of(1, 2, 3, 5).allMatch(o -> o > 0);
        System.out.println(b);
        // anyMatch操作用于判断Stream中的是否有满足指定条件的元素。如果最少有一个满足条件返回true，否则返回false。
        boolean b1 = Stream.of(1, 2, 3, 4).anyMatch(x -> x > 3);
        System.out.println(b1);
        // findAny操作用于获取含有Stream中的某个元素的Optional，如果Stream为空，则返回一个空的Optional。由于此操作的行动是不确定的，其会自由的选择Stream中的任何元素。
        Optional<Integer> any = Stream.of(1, 2, 3, 4).findAny();
        System.out.println(any.get());
        // findFirst操作用于获取含有Stream中的第一个元素的Optional，如果Stream为空，则返回一个空的Optional。若Stream并未排序，可能返回含有Stream中任意元素的Optional。
        Optional<Integer> first = Stream.of(1, 2, 3, 4).findFirst();
        System.out.println(first.get());
        // limit方法将截取原Stream，截取后Stream的最大长度不能超过指定值N。如果原Stream的元素个数大于N，将截取原Stream的前N个元素；如果原Stream的元素个数小于或等于N，将截取原Stream中的所有元素
        Stream.of(1, 2, 3, 4).limit(3).forEach(x -> System.out.print(x + " "));
        System.out.println();
        // noneMatch方法将判断Stream中的所有元素是否满足指定的条件，如果所有元素都不满足条件，返回true；否则，返回false.
        System.out.println(Stream.of(1, 2, 3, 4).noneMatch(x -> x == 5));
    }
}
